use super::http::do_get;
use dotenv as env;
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
pub struct AmapResp {
    pub count: String,
    pub infocode: String,
    pub pois: Vec<Poi>,
    pub status: String,
    pub info: String,
}

#[derive(Debug, Deserialize)]
pub struct Poi {
    pub parent: String,
    pub address: String,
    pub distance: String,
    pub pcode: String,
    pub adcode: String,
    pub pname: String,
    pub cityname: String,
    pub r#type: String,
    pub typecode: String,
    pub adname: String,
    pub citycode: String,
    pub name: String,
    pub location: String,
    pub id: String,
}

pub async fn get_longitude_and_latitude(address: String) -> Result<String, String> {
    let key = env::var("amap.secret").map_err(|_| " 'amap.secret' not settle".to_string())?;

    let mut map: HashMap<&str, &str> = HashMap::new();
    map.insert("key", &key);
    map.insert("keywords", &address);

    let shop_coordinate = do_get::<AmapResp>("https://restapi.amap.com/v5/place/text", Some(map))
        .await
        .unwrap();

    if !shop_coordinate.status.eq("1") {
        return Err("店铺地址解析失败".to_string());
    }

    Ok(shop_coordinate.pois[0].location.clone())
}

#[derive(Debug, Serialize, Deserialize)]
pub struct LineResp {
    pub status: String,
    pub info: String,
    pub infocode: String,
    pub count: String,
    pub route: AmapRoute,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AmapRoute {
    pub origin: String,
    pub destination: String,
    pub taxi_cost: String,
    pub paths: Vec<AmapPath>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AmapPath {
    pub distance: String,
    pub restriction: String,
    pub steps: Vec<AmapStep>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AmapStep {
    pub instruction: String,
    pub orientation: String,
    #[serde(rename = "step_distance")]
    pub step_distance: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub road_name: Option<String>,
}

pub async fn directionlite(src: String, dest: String) -> Result<u64, String> {
    let key = env::var("amap.secret").map_err(|_| " 'amap.secret' not settle".to_string())?;
    let mut map: HashMap<&str, &str> = HashMap::new();
    map.insert("key", &key);
    map.insert("origin", &src);
    map.insert("destination", &dest);

    let line = do_get::<LineResp>("https://restapi.amap.com/v5/direction/driving", Some(map))
        .await
        .unwrap();

    if !line.status.eq("1") {
        return Err("配送路线规划失败".to_string());
    }

    let mut distance: u64 = 0;

    let _ = line.route.paths.clone().into_iter().for_each(|x| {
        if let Ok(value) = x.distance.parse::<u64>() {
            distance += value;
        } else {
            println!("解析失败，跳过无效值: {}", x.distance);
        }
    });
    Ok(distance)
}
